package SentenceTranslator;

import Include.ASMConstructor;
import Common.REG;
import Include.TACLine;
import Common.TacOperandType;
import Common.RelacedEeg;
import Common.POSTYPE;

import java.util.ArrayList;
import java.util.List;

import Main.SymbolManager;

public class CommonTranslator {
    public List<String> ASMLines;

    public List<String> SentenceTranslate(SymbolManager SymbolManager_, TACLine TACLine_) {
        ASMLines = new ArrayList<String>();
        String str_dst_encode = SymbolManager_.encodeVar(TACLine_.dst.value);
        String str_src1 = TACLine_.src1.value;
        String str_src2 = TACLine_.src2.value;
        String op_string = TACLine_.op.commonop2String();
        REG reg_dst = REG.Cnts;

        if (TACLine_.src1.operType == TacOperandType.IMM) {
            reg_dst = SymbolManager_.getReg(str_dst_encode, "");
            if (reg_dst == REG.Cnts) {
                RelacedEeg replaced_reg = SymbolManager_.getReplacedReg();
                reg_dst = replaced_reg.reg;
                SymbolManager_.pushReg(reg_dst, 1);
                ASMLines.add(ASMConstructor.construct_asm("push", reg_dst));
            }
            ASMLines.add(ASMConstructor.construct_asm("mov", reg_dst, str_src1));
        } else {
            String str_src1_encode = SymbolManager_.encodeVar(str_src1);
            reg_dst = SymbolManager_.getReg(str_dst_encode, str_src1_encode);

            if (reg_dst == REG.Cnts) {
                RelacedEeg replaced_reg = SymbolManager_.getReplacedReg();
                reg_dst = replaced_reg.reg;
                SymbolManager_.pushReg(reg_dst, 1);
                ASMLines.add(ASMConstructor.construct_asm("push", reg_dst));
            }

            POSTYPE pos = SymbolManager_.position(str_src1_encode);

            if (pos == POSTYPE.REG) {
                REG reg_src1 = SymbolManager_.avalueReg(str_src1_encode);
                if (reg_dst != reg_src1) {
                    ASMLines.add(ASMConstructor.construct_asm("mov", reg_dst, reg_src1));
                } else {
                    SymbolManager_.pushReg(reg_src1, 1);
                    ASMLines.add(ASMConstructor.construct_asm("push", reg_src1));
                }
            } else if (pos == POSTYPE.MEM) {
                int mem_src1 = SymbolManager_.avalueMem(str_src1_encode);
                ASMLines.add(ASMConstructor.construct_asm("mov", reg_dst, Integer.toString(mem_src1)));
            } else if (pos == POSTYPE.GLOBAL) {
                ASMLines.add(ASMConstructor.construct_asm("mov", reg_dst, str_src1));
            } else {
                System.out.println("common default error");
            }
        }

        if (TACLine_.src2.operType == TacOperandType.IMM) {
            ASMLines.add(ASMConstructor.construct_asm(op_string, reg_dst, str_src2));
        } else if (TACLine_.src2.operType == TacOperandType.VAR) {
            String str_src2_encode = SymbolManager_.encodeVar(str_src2);
            POSTYPE pos = SymbolManager_.position(str_src2_encode);

            if (pos == POSTYPE.REG) {
                REG reg_src2 = SymbolManager_.avalueReg(str_src2_encode);
                ASMLines.add(ASMConstructor.construct_asm(op_string, reg_dst, reg_src2));
            } else if (pos == POSTYPE.MEM) {
                int mem_src2 = SymbolManager_.avalueMem(str_src2_encode);
                ASMLines.add(ASMConstructor.construct_asm(op_string, reg_dst, Integer.toString(mem_src2)));
            } else if (pos == POSTYPE.GLOBAL) {
                ASMLines.add(ASMConstructor.construct_asm(op_string, reg_dst, str_src2));
            } else {
                System.out.println("common default error");
            }
        }

        if (reg_dst != REG.EDI) {
            SymbolManager_.setAvalueReg(str_dst_encode, reg_dst);
        }
        if (SymbolManager_.avalueMem(str_dst_encode) != -1) {
            int dst_mem = SymbolManager_.avalueMem(str_dst_encode);
            ASMLines.add(ASMConstructor.construct_asm("mov", Integer.toString(dst_mem), reg_dst));
        }
        return ASMLines;
    }

}